/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Logica;

/**
 *
 * @author Edder
 */
public class Cocomo {
    private static float[][] ESFUERZO_ENTERO = {
        {2.4f,1.05f},
        {3.0f,1.12f},
        {3.6f,1.5f}
    };
    private static float[][] ESFUERZO_DECIMAL = {
        {5f, 21.3f, 91f, 392f,0},
        {6.5f, 31f, 146f, 687f, 3253f},
        {8.3f, 44f, 230f, 1216f, 6428f}
    };
           
    private static float[] TIEMPO_DESARROLLO = { 0.38f, 0.35f, 0.32f };
        
    private static int PEQUEÑO = 2;
    private static int INTERMEDIO = 8;
    private static int MEDIANO = 32;
    private static int GRANDE = 128;
    private static int MUY_GRANDE = 152;    
        
    private static int POO = 1;
    
    private int metodologia = 0;
    private int tipoProyecto = 0;
    private double spm = 0d;

    public Cocomo(int metodologia, int tipoProyecto, double spm) {
        this.metodologia = metodologia;
        this.tipoProyecto = tipoProyecto;
        this.spm = spm;
    }
        
    public int funciones(int rs){
        if(metodologia == POO){
            return 280 * rs;
        }else{
            return 420 * rs;
        }
    }
    
    public float milesFunciones(int funciones){
        return (float)funciones/1000;
    }
    
    public float esfuerzo(float mf){
        if ( mf < 2 || mf > 512 || esEntero(mf)){
            return (float) (ESFUERZO_ENTERO[tipoProyecto-1][0] * Math.pow(mf, ESFUERZO_ENTERO[tipoProyecto-1][1]));
        }else{
            int menor;
            int mayor;
            if (mf < INTERMEDIO){
                menor = PEQUEÑO;
                mayor = INTERMEDIO;
            }else if( mf < MEDIANO){
                menor = INTERMEDIO;
                mayor = MEDIANO;
            }else if( mf < GRANDE){
                menor = MEDIANO;
                mayor = GRANDE;
            }else{
                menor = GRANDE;
                mayor = MUY_GRANDE;
            }
            return interpolacion(menor, mayor, mf);
        }
    }    
    
    public float interpolacion(int menor, int mayor, float mf){
        int posMenor = 0;
        int posMayor;
        
        switch(menor){
            case 2: 
                posMenor = 0;
                break;
            case 8:
                posMenor = 1;                
                break;
            case 32:
                posMenor = 2;
                break;
            case 128:
                posMenor = 3;
                break;                
        }
        posMayor = posMenor + 1;
        return ESFUERZO_DECIMAL[tipoProyecto-1][posMenor] + 
                ((mf - (float)menor)/((float)mayor - (float)menor)) * 
                (ESFUERZO_DECIMAL[tipoProyecto-1][posMayor] - ESFUERZO_DECIMAL[tipoProyecto-1][posMenor] );
    }
    
    public boolean esEntero(float num){
        int entero = (int) num;
        if ( num - entero == 0){
            return true;            
        }else{
            return false;
        }
    }
    
    public float tiempoDesarrollo(float esfuerzo){
        return (float) (2.5f * Math.pow(esfuerzo, TIEMPO_DESARROLLO[tipoProyecto-1]));
    }
    
    public float cantidadHombresMes(float esfuerzo, float tiempoDesarrollo){
        return esfuerzo / tiempoDesarrollo;
    }
    
    public float productividad(float funciones, float esfuerzo){
        return funciones / esfuerzo;
    }
    
    public float costoDesarrollo(float esfuerzo){
        return esfuerzo * 2f * (float)spm;
    }
}
